import animate from "@/utils/animate"
import { clearRect } from '@/utils/common'

export default {

  data() {
    return {
      isPauseValue: false
    }
  },

  mounted() {
    this.initCanvas()
    this.registEvent()
    this.init()
  },

  methods: {
    initCanvas() {
      const { Canvas } = this.$refs
      this.canvas = document.getElementById('canvas')
      let dpr = window.devicePixelRatio
      this.canvas.width = Canvas.clientWidth * dpr
      this.canvas.height = (Canvas.clientHeight - 10) * dpr
      let ctx = this.canvas.getContext('2d');
      ctx.font = 'bold ' + (14 * dpr) + 'px serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      this.ctx = ctx
    },

    skipBack(toIndex) {
      if (this.curStep != 0) {
        this.transit(this.curStep, toIndex, () => {
          this.curStep = toIndex
          this.afterSkipBack()
        })
      }
    },

    preSkipBack() {
      this.skipBack(0)
    },

    afterSkipBack() {

    },

    /**
     * 动画过渡
     */
    transit(fromIndex, toIndex, callback) {
      if (callback) {
        clearInterval(this.stepTimer)
        this.$bus.$emit('setIsPause')
      }

      if (!this.lock) {
        this.lock = true
        animate(this.steps[fromIndex], this.steps[toIndex], this, this.delay, () => {
          this.lock = false
          callback && callback()
          this.afterTransit()
        })
      }
    },

    afterTransit() {
      this.$bus.$emit('progress', Math.ceil(this.curStep / (this.steps.length - 1) * 100))
    },

    stepBack() {
      if (this.curStep != 0) {
        this.transit(this.curStep, this.curStep - 1, () => {
          --this.curStep
          this.afterStepBack()
        })
      }
    },

    preStepBack() {
      this.stepBack()
    },

    afterStepBack() {

    },

    stepForward() {
      if (this.curStep < this.steps.length - 1) {
        this.transit(this.curStep, this.curStep + 1, () => {
          ++this.curStep
          this.afterStepForward()
        })
      }
    },

    preStepForward() {
      this.stepForward()
    },

    afterStepForward() {

    },

    skipForward() {
      if (this.curStep < this.steps.length - 1) {
        this.transit(this.curStep, this.steps.length - 1, () => {
          this.curStep = this.steps.length - 1
          this.afterSkipForward()
        })
      }
    },

    preSkipForward() {
      this.skipForward()
    },

    afterSkipForward() {

    },

    pauseOrPlay(isPause) {
      this.$bus.$emit('setIsPause', isPause)
      if (isPause) {
        clearInterval(this.stepTimer)
        return
      }

      this.stepTimer = setInterval(() => {
        if (this.curStep >= this.steps.length - 1) {
          clearInterval(this.stepTimer)
          this.afterPauseOrPlay()
          return
        }

        if (this.steps[this.curStep +  1].includes('skip')) {
          this.curStep ++
        }
        this.transit(this.curStep, ++this.curStep)
      }, this.delay)
    },

    prePauseOrPlay(isPause) {
      this.pauseOrPlay(isPause)
    },

    afterPauseOrPlay() {
      this.$bus.$emit('setIsPause')
    },


    skipCurProgress(curProgress) {
      clearInterval(this.stepTimer)
      let s = Math.round(curProgress * (this.steps.length - 1) / 100)
      this.transit(this.curStep, s, () => {
        this.curStep = s
        this.afterSkipCurProgress()
      })
    },

    preSkipCurProgress(curProgress) {
      this.skipCurProgress(curProgress)
    },

    afterSkipCurProgress() {

    },


    setDelay(delay) {
      this.delay = delay
    },

    clearCanvas() {
      clearRect(this.ctx, 0, 0, this.$refs.Canvas.clientWidth, this.$refs.Canvas.clientHeight)
    },

    init() {
      this.curStep = 0
      this.lock = false
      // 存储所有的步骤
      this.steps = []
      this.delay = 400
      clearInterval(this.animateTimer)
      clearInterval(this.stepTimer)
      this.clearCanvas()
      this.$bus.$emit('progress', 0)
      this.$bus.$emit('setIsPause')
    },

    doClear(callback) {
      // 清空画布操作，先暂停演示
      this.pauseOrPlay(true)
      // 为了防止动画正在演示，造成清空失败
      if (!this.lock) {
        this.$bus.$emit('setIsPause')
        // 清空画布
        this.clearCanvas()
        // 步骤置空
        this.steps = []
        // 进度条置0
        this.$bus.$emit('progress', 0)
        // 步骤置于最开始的状态
        this.curStep = 0
        // 清空画布
        this.clearCanvas()
        callback && callback()
      }
    },

    // 操作成功
    operSucess(message) {
      this.$message({
        message,
        type: 'success',
        offset: 50,
        duration: 2000,
        center: true,
        showClose: true
      });
    },

    // 操作警告
    operWarn(message) {
      this.$message({
        message,
        type: 'warning',
        offset: 50,
        duration: 2000,
        center: true,
        showClose: true
      });
    },

    setIsPauseValue(isPauseValue) {
      this.isPauseValue = isPauseValue
    },

    registEvent() {
      this.$bus.$on('skipBack', () => {
        this.preSkipBack()
      })

      this.$bus.$on('stepBack', () => {
        this.preStepBack()
      })

      this.$bus.$on('pauseOrPlay', (isPause) => {
          this.prePauseOrPlay(isPause)
      })

      this.$bus.$on('stepForward', () => {
        this.preStepForward()
      })

      this.$bus.$on('skipForward', () => {
        this.preSkipForward()
      })

      this.$bus.$on('delay', (value, isPause) => {
        this.setDelay(value)
        clearInterval(this.stepTimer)
        this.prePauseOrPlay(isPause)
      })

      this.$bus.$on('skipCurProgress', curProgress => {
        if (this.steps.length === 0) {
          this.$bus.$emit('progress', 0)
        } else {
          this.preSkipCurProgress(curProgress)
        }
      })

      this.$bus.$on('getIsPauseValue', value => {
        this.setIsPauseValue(value)
      })
    },

    destroyEvent() {
      this.$bus.$off('skipBack')
      this.$bus.$off('stepBack')
      this.$bus.$off('pauseOrPlay')
      this.$bus.$off('stepForward')
      this.$bus.$off('skipForward')
      this.$bus.$off('delay')
      this.$bus.$off('skipCurProgress')
      this.$bus.$off('getIsPauseValue')
    }
  },

  beforeDestroy() {
    clearInterval(this.animateTimer)
    clearInterval(this.stepTimer)
    this.destroyEvent()
  },


}